﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using LispInterpretor.HelperClasses;

namespace LispInterpretor.Parsers
{
    public class ListParser : IParser
    {
        public bool Is(string text, Environment environment)
        {
            return text.StartsWith("(") && text.EndsWith(")");
        }

        public object Evaluate(string text, Environment environment)
        {
            IList<object> result = new Collection<object>();

            IList<string> parsedItems = ParserHelper.ParseArguments(text);

            foreach (string parsedItem in parsedItems)
            {
                object evalResult = Evaluator.Eval(parsedItem, environment);

                result.Add(evalResult);
            }

            if (result.Count > 0 && result[0] is Procedure)
            {
                return InvokeProcedure(result);
            }

            return result;
        }

        private static object InvokeProcedure(IList<object> result)
        {
            Procedure proc = result[0] as Procedure;

            int length = result.Count;

            object[] resultArray = new object[length];

            result.CopyTo(resultArray, 0);

            object[] argumentArray = new object[length - 1];
            Array.Copy(resultArray, 1, argumentArray, 0, length - 1);

            return proc.Apply(argumentArray);
        }
    }
}
